<template>
  <view class="doubao-chat-container">
    <!-- 使用封装的顶部导航栏组件 -->
    <chat-header 
      :title="'新如影'" 
      :subtitle="'xryai.cn'" 
      :is-voice-playing="isVoicePlaying"
      :speaker-enabled="speakerEnabled"
      :is-logged-in="isLoggedIn"
      @go-back="handleGoBack"
      @make-phone-call="makePhoneCall"
      @toggle-voice-play="toggleVoicePlay"
      @toggle-speaker="toggleSpeaker"
      @open-header-menu="openHeaderMenu"
      @go-to-login="goToLogin"
      ref="chatHeader"
    />
    
    <!-- 聊天内容区域 (MessageList) -->
    <chat-messages
      :messages="messages"
      :scroll-to-view="scrollToView"
      :content-padding="{ top: headerHeight + 'px', bottom: chatContentPaddingBottom }"
      :is-synthesizing="isSynthesizing"
      :synthesizing-message-id="synthesizingMessageId"
      @load-more="loadMoreMessages"
      @play-voice="playVoice"
      @copy-message="copyMessage"
      @play-tts="playTTSFromCache"
      @favorite-message="favoriteMessage"
      @share-message="shareMessage"
      @retry-message="retryMessage"
      ref="chatMessages"
    />
    
    <!-- 使用封装的ChatInput组件替换原有输入区域 -->
    <chat-input
      :safeAreaBottom="safeAreaBottom"
      @send-message="handleSendMessage"
      @quick-action="handleQuickAction"
      @choose-image="chooseImage"
      @toggle-function-buttons="toggleFunctionButtons"
      @input-focus="handleInputFocus"
      @input-blur="handleInputBlur"
      @start-recording="startRecording"
      @stop-recording="stopRecording"
      @cancel-recording="cancelRecording"
      @height-change="updateChatFooterHeight"
    />
    
    <!-- 录音状态遮罩层 - 移至ChatInput组件内部处理 -->
  		<!-- 椭圆形导航栏 -->
		<EllipseTabBar />
	</view>
</template>


<script>
// 导入封装的顶部导航栏组件
import ChatHeader from '@/components/ChatHeader.vue';
// 导入语音合成服务和语音识别服务
import TTSService from '@/api/ttsService.js';
import TTSStreamService from '@/api/ttsStreamService.js';
import IflytekSpeechService from '@/api/iflytekSpeechService.js';
// 导入ChatInput组件
import ChatInput from '@/components/ChatInput.vue';
// 导入ChatMessages组件
import ChatMessages from '@/components/ChatMessages.vue';
// 导入椭圆形导航栏组件
import EllipseTabBar from '@/components/EllipseTabBar.vue';

export default {
  components: {
    ChatHeader,
    ChatInput,
    ChatMessages,
    EllipseTabBar
  },
  data() {
    return {
      inputMessage: '',
      inputMode: 'text', // 'text' 或 'voice'
      messages: [
        {
          id: '1',
          type: 'text',
          sender: 'bot',
          content: '你好呀！我是来自新如影的AI导游，我叫小影，我可以给点关于旅游的建议你？',
          timestamp: Date.now()
        }
      ],
      scrollToView: '',
      showFunctionButtons: false,
      recorder: null,
      audioContext: null,
      recordingStart: 0,
      recordDuration: 0,
      safeAreaBottom: 0, // 底部安全区域高度
      moreButtonActive: false, // 加号按钮状态跟踪
      textareaHeight: 28, // 文本区域默认高度，从38px改为28px
      isExpandedView: false, // 是否展开大视图
      cursorPosition: 0, // 光标位置
      textLines: 1, // 文本行数，默认为1行
      isVoicePlaying: false, // 添加语音播放状态
      isRecording: false,
      isCancelling: false,
      touchStartY: 0,
      activeWaveDot: 20, // 当前激活的波形点
      waveDotInterval: null,
      speechService: null, // 语音识别服务实例
      
      // 对接扣子工作流 API
      cozeApi: {
        url: 'https://api.coze.cn/v1/workflow/stream_run',
        apiKey: 'pat_7e4Na429IrQ9cnT2GvzHdJ7cokBV5BsOqgInvpBZRA6AfZq1v9Fcu5gbLFil8zTc',
        workflowId: '7516771193598115867',//7514767522853552179   7516771193598115867
        userId: 'user_' + Math.random().toString(36).substring(2, 10),
        conversationId: 'conv_' + Date.now().toString()
      },
      isLoadingResponse: false,
      // -- TTS API CONFIG --
      // 在此填入您从火山引擎控制台获取的TTS应用信息
      // https://console.volcengine.com/speech/app/list
      huoshanTTSApi: {
        url: 'https://openspeech.bytedance.com/api/v1/tts',
        appid: '2832197978', // 您的AppID
        accessToken: 'yfoQIGAJj7lAqt6LKxVWQDVpj4hhUtI8', // 您的Access Token
        voiceType: 'zh_male_M392_conversation_wvae_bigtts', // 发音人音色
        cluster: 'volcano_tts'
      },
      // --讯飞 ASR API CONFIG --
      iflytekASRApi: {
        appid: '9f230f94',
        apiKey: '94b9d70ea1706aaa01d9333ef60946be',
        apiSecret: 'OWQ1YTRiMGM2MWNhMmVjOTM3ZjdmOWFl',
      },
      ttsAudioContext: null, // TTS 专用音频播放器实例
      ttsAudioCache: {}, // 语音缓存对象，key为消息ID，value为base64音频数据
      lastBotMessageId: null, // 最后一条AI消息的ID
      speakerEnabled: true, // 默认开启自动语音播放
      isSynthesizing: false, // 是否正在合成语音
      synthesizingMessageId: null, // 正在合成语音的消息ID
      normalInputHeight: 300, // 从150增加到170，为键盘和输入框提供更多空间
      expandedInputHeight: 320, // 增加展开输入区域高度
      chatFooterHeight: 0, // 当前输入区实际高度
      isLoggedIn: false, // 跟踪登录状态
      headerHeight: 80, // 默认高度，防止闪烁
      ttsStreamService: null, // 流式TTS服务实例
      isStreamingSynthesis: false, // 是否正在流式合成
      currentTextSegments: null, // 当前正在处理的文本段落
    }
  },
  computed: {
    // 计算聊天内容区域底部padding
    chatContentPadding() {
      // 根据当前输入模式返回合适的底部padding
      return this.isExpandedView ? this.expandedInputHeight + 'px' : this.normalInputHeight + 'px';
    },
    chatContentPaddingBottom() {
      // 底部内边距 = 输入框高度
      return `${this.chatFooterHeight}px`;
    }
  },
  onShow() {
    // 每次页面显示时都更新登录状态
    this.isLoggedIn = !!uni.getStorageSync('isLoggedIn');
  },
  onLoad() {
    // 检查登录状态
    this.checkLoginStatus();
    
    // 初始化录音管理器
    this.recorder = uni.getRecorderManager();
    
    // 初始化SpeechService (使用新的ASR配置)
    this.speechService = new IflytekSpeechService({
      appid: this.iflytekASRApi.appid,
      apiKey: this.iflytekASRApi.apiKey,
      apiSecret: this.iflytekASRApi.apiSecret,
    });
    
    // 监听录音相关事件
    this.recorder.onStop((res) => {
      if (this.recordDuration < 1) {
        uni.showToast({
          title: '说话时间太短',
          icon: 'none'
        });
        return;
      }
      
      // 调用语音识别服务
      if (this.speechService) {
        this.speechService.recognizeAudio(res.tempFilePath)
          .then(result => {
            if (result && result.text) {
              const trimmedText = result.text.trim();
              // 检查识别结果是否有效（不为空或仅为标点）
              if (trimmedText && trimmedText !== '。') {
                this.handleSendMessage(trimmedText);
              } else {
                uni.showToast({
                  title: '未能识别到有效语音',
                  icon: 'none'
                });
              }
            } else {
              // 处理未能识别但API成功调用的情况
              uni.showToast({
                title: '未能识别您的语音',
                icon: 'none'
              });
            }
          })
          .catch(error => {
            // 使用封装的错误处理方法获取友好提示
            const errorMessage = this.speechService.getErrorMessage(error.code);
            uni.showToast({
              title: errorMessage,
              icon: 'none'
            });
            console.error('语音识别错误:', error);
          });
      } else {
        // 降级处理：如果服务未初始化，执行旧逻辑
        console.warn("SpeechService未初始化，执行旧的发送语音消息逻辑");
        this.sendVoiceMessage(res.tempFilePath, this.recordDuration);
      }
    });
    
    this.recorder.onError((res) => {
      console.error('录音失败', res);
      uni.showToast({
        title: '录音失败',
        icon: 'none'
      });
    });
    
    // 初始化时创建音频上下文
    this.audioContext = uni.createInnerAudioContext();
    this.audioContext.onPlay(() => {
      console.log('开始播放');
      this.isVoicePlaying = true;
    });
    this.audioContext.onEnded(() => {
      console.log('播放结束');
      this.isVoicePlaying = false;
    });
    this.audioContext.onError((res) => {
      console.error('播放错误:', res.errMsg);
      this.isVoicePlaying = false;
        uni.showToast({
        title: '播放失败',
          icon: 'none'
        });
    });

    // -- TTS播放器初始化 --
    this.ttsAudioContext = uni.createInnerAudioContext();
    this.ttsAudioContext.onPlay(() => {
        this.isVoicePlaying = true;
        console.log('TTS开始播放');
    });
    this.ttsAudioContext.onEnded(() => {
        this.isVoicePlaying = false;
        console.log('TTS播放结束');
    });
    this.ttsAudioContext.onStop(() => {
        this.isVoicePlaying = false;
        console.log('TTS播放停止');
    });
    this.ttsAudioContext.onError((res) => {
        this.isVoicePlaying = false;
        console.error('TTS播放错误:', res.errMsg);
        uni.showToast({
            title: 'TTS播放失败',
            icon: 'none'
        });
    });

    // -- 流式TTS服务初始化 --
    this.ttsStreamService = new TTSStreamService({
      appId: this.huoshanTTSApi.appid,
      accessKey: this.huoshanTTSApi.accessToken,
      resourceId: 'volc.service_type.10029', // 使用单向流式API的资源ID
      speaker: this.huoshanTTSApi.voiceType
    });
    
    // 设置流式TTS回调
    this.ttsStreamService.setCallbacks({
      onStart: () => {
        this.isVoicePlaying = true;
        console.log('流式TTS开始播放');
      },
      onData: (chunk) => {
        // 可以在这里处理每个音频数据块
        console.log('收到流式TTS数据块');
      },
      onEnd: () => {
        this.isVoicePlaying = false;
        this.synthesizingMessageId = null;
        console.log('流式TTS播放结束');
      },
      onError: (error) => {
        this.isVoicePlaying = false;
        this.synthesizingMessageId = null;
        console.error('流式TTS错误:', error);
        uni.showToast({
          title: '语音播放失败',
          icon: 'none'
        });
      }
    });

    // 获取安全区域信息
    this.getSafeAreaBottom();
    
    // 为初始消息设置ID并预合成语音
    if (this.messages.length > 0 && this.messages[0].sender === 'bot') {
      // 确保第一条消息有唯一ID
      if (!this.messages[0].id || this.messages[0].id === '1') {
        this.messages[0].id = 'welcome_' + Date.now();
      }
      
      this.lastBotMessageId = this.messages[0].id;
      
      // 延迟一段时间后预合成欢迎语音
      setTimeout(() => {
        console.log('准备合成初始消息语音:', this.messages[0].content);
        const welcomeText = this.messages[0].content.replace(/<[^>]*>/g, '');
        if (welcomeText && welcomeText.trim()) {
          // 根据扩音器状态决定是否自动播放
          const silent = !this.speakerEnabled;
          this.synthesizeTTS(welcomeText, this.messages[0].id, silent);
        }
      }, 1000); // 延迟1秒，确保页面和服务都已完全加载
    }
    
    // 计算输入区域高度
    this.calculateInputAreaHeight();
  },
  mounted() {
    this.calculateHeaderHeight();
  },
  beforeDestroy() {
    // 释放资源
    if (this.ttsStreamService) {
      this.ttsStreamService.stop();
    }
    if (this.ttsAudioContext) {
      this.ttsAudioContext.destroy();
    }
    if (this.audioContext) {
      this.audioContext.destroy();
    }
  },
  methods: {
    updateChatFooterHeight(height) {
      if (height) {
        this.chatFooterHeight = height;
      }
    },
    calculateHeaderHeight() {
      this.$nextTick(() => {
        const query = uni.createSelectorQuery().in(this.$refs.chatHeader);
        query.select('.chat-header').boundingClientRect(data => {
          if (data) {
            this.headerHeight = data.height;
          }
        }).exec();
      });
    },
    // Custom UTF-8 decoder for streaming data, as a fallback for TextDecoder
    decodeUtf8Stream(data) {
      const decoder = new TextDecoder('utf-8');
      
      // 尝试找到完整的UTF-8序列
      let validEnd = data.length;
      for (let i = data.length - 1; i >= Math.max(data.length - 4, 0); i--) {
        const byte = data[i];
        // 检查非完整UTF-8序列的开始
        if ((byte & 0xC0) === 0x80) {
          // 这是一个后续字节，继续往前找
          continue;
        } else if ((byte & 0xE0) === 0xC0) {
          // 2字节序列开始
          if (data.length - i < 2) {
            validEnd = i;
          }
          break;
        } else if ((byte & 0xF0) === 0xE0) {
          // 3字节序列开始
          if (data.length - i < 3) {
            validEnd = i;
          }
          break;
        } else if ((byte & 0xF8) === 0xF0) {
          // 4字节序列开始
          if (data.length - i < 4) {
            validEnd = i;
          }
          break;
        } else {
          // 单字节或无效序列
          break;
        }
      }
      
      // 分割数据为有效部分和剩余部分
      const validData = data.slice(0, validEnd);
      const remainder = data.slice(validEnd);
      
      try {
        return {
          text: decoder.decode(validData),
          remainder: remainder
        };
      } catch (e) {
        console.error('UTF-8解码失败:', e);
        return { text: '', remainder: data };
      }
    },
    // 检查登录状态
    checkLoginStatus() {
      const isLoggedIn = uni.getStorageSync('isLoggedIn');
      this.isLoggedIn = !!isLoggedIn;
      if (!isLoggedIn) {
        uni.navigateTo({
          url: '../user/login/index',
          success: function() {
            console.log('跳转到登录页面成功');
          },
          fail: function(err) {
            console.error('跳转到登录页面失败:', err);
          }
        });
      } else {
        // 获取用户名显示欢迎信息
        const username = uni.getStorageSync('username');
        if (username) {
          console.log(`欢迎回来，${username}`);
        }
      }
    },
    
    // 添加手动滚动到底部的方法
    scrollToBottom() {
      if (this.$refs.chatMessages) {
        this.$refs.chatMessages.scrollToBottom();
      }
    },
    
    // 获取底部安全区域高度
    getSafeAreaBottom() {
      uni.getSystemInfo({
        success: (res) => {
          // 获取安全区域的底部边距
          if (res.safeArea) {
            this.safeAreaBottom = res.screenHeight - res.safeArea.bottom;
          }
        }
      });
    },
    
    // 处理消息发送
    handleSendMessage(message) {
      // 检查登录状态
      const isLoggedIn = uni.getStorageSync('isLoggedIn');
      if (!isLoggedIn) {
        uni.navigateTo({
          url: '../user/login/index'
        });
        return;
      }
      
      // 如果传入的是纯文本，则创建文本消息对象
      if (typeof message === 'string') {
      // 保存用户输入的内容
      const userMessage = message.trim();
      
      // 创建新消息对象
      const newMessage = {
        id: Date.now().toString(),
        type: 'text',
        sender: 'user',
        content: userMessage,
        timestamp: Date.now(),
        status: 'sent'
      };
      
      // 添加到消息列表
      this.messages.push(newMessage);
        
        // 确保在发送消息后滚动到底部
        this.scrollToBottom();
      
      // 调用 Coze API
      this.fetchCozeResponse(userMessage);
      } else {
        // 如果传入的是对象（比如图片消息），直接添加到消息列表
        this.messages.push(message);
        this.scrollToView = 'msg-' + (this.messages.length - 1);
      
        // 确保在发送消息后滚动到底部
        this.scrollToBottom();
      }
    },
    
    // 处理快捷操作按钮点击
    handleQuickAction(action) {
      // 根据不同的操作类型执行不同的操作
      switch(action) {
        case 'planning':
          this.sendQuickMessage('大理有啥玩');
          break;
        case 'photo':
          this.sendQuickMessage('大理有啥吃');
          break;
        case 'spot':
          this.sendQuickMessage('大理民宿');
          break;
        default:
          console.log('未知的快捷操作:', action);
      }
    },
    
    // 处理输入框获取焦点
    handleInputFocus() {
      // 输入框获取焦点时隐藏功能按钮
      this.showFunctionButtons = false;
      this.moreButtonActive = false;
    },
    
    // 处理输入框失去焦点
    handleInputBlur() {
      // 如果需要在输入框失去焦点时执行特定操作
      console.log('输入框失去焦点');
    },
    
    handleGoBack() {
      uni.navigateBack();
    },
    
    // 修改发送消息方法，接入API
    sendMessage() {
      if (!this.inputMessage.trim()) return;
      
      // 创建新消息对象
      const newMessage = {
        id: Date.now().toString(),
        type: 'text',
        sender: 'user',
        content: this.inputMessage,
        timestamp: Date.now(),
        status: 'sent'
      };
      
      // 保存用户输入的内容
      const userMessage = this.inputMessage.trim();
      
      // 添加到消息列表
      this.messages.push(newMessage);
      
      // 清空输入框
      this.inputMessage = '';
      
      // 重置输入状态
      this.resetInputState();
      
      // 关闭扩展视图（如果打开的话）
      this.isExpandedView = false;
      
      // 调用 Coze API
      this.fetchCozeResponse(userMessage);
      
      // 滚动到最新消息
      this.scrollToLatestMessage();
    },
    
    // 调用 Coze 流式 API
    fetchCozeResponse(userMessage, tempMessageId = null) {
      this.isLoadingResponse = true;
      
      // 如果没有传入tempMessageId，创建一个新的临时消息
      let tempMessage;
      if (!tempMessageId) {
        tempMessage = {
          id: 'temp-' + Date.now().toString(),
          type: 'text',
          sender: 'bot',
          content: '',
          timestamp: Date.now(),
          status: 'loading'
        };
        this.messages.push(tempMessage);
      // 滚动到底部
      this.$nextTick(() => {
        this.scrollToBottom();
      });
      } else {
        // 使用已有的临时消息ID
        tempMessage = { id: tempMessageId };
      }
      
      const requestData = {
        workflow_id: this.cozeApi.workflowId,
        parameters: {
          user_query: userMessage,
          user_id: this.cozeApi.userId,
          conversation_id: this.cozeApi.conversationId
        },
        stream: true // 确保启用流式传输
        };
        
      console.log('Coze API Request:', JSON.stringify(requestData, null, 2));

      // 添加请求超时处理
      let requestTimeout = setTimeout(() => {
        console.error('请求超时');
        this.handleStreamError(tempMessage.id, '请求超时，请检查网络连接或稍后再试。');
      }, 30000); // 30秒超时
      
      try {
      const requestTask = uni.request({
        url: this.cozeApi.url,
        method: 'POST',
        data: requestData,
        header: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${this.cozeApi.apiKey}`
        },
        enableChunked: true, // 启用分块接收
        success: (res) => {
            // 清除超时定时器
            clearTimeout(requestTimeout);
            
            // 检查响应状态码
            if (res.statusCode !== 200) {
              console.error('请求失败，状态码:', res.statusCode);
              this.handleStreamError(tempMessage.id, `请求失败 (${res.statusCode})，请稍后再试。`);
              return;
            }
            
          console.log('Request finished successfully', res);
        },
        fail: (err) => {
            // 清除超时定时器
            clearTimeout(requestTimeout);
            
          console.error('Request failed:', err);
            this.handleNetworkError(tempMessage.id, err);
        }
      });
      
      let buffer = '';
      let aiMessageIndex = -1;
        let incompleteChunk = new Uint8Array(0); // For storing incomplete UTF-8 sequences

      requestTask.onChunkReceived((res) => {
        try {
            // 清除超时定时器，因为已经开始接收数据
            clearTimeout(requestTimeout);
            
            // Combine previous incomplete chunk with the new data
            const newChunk = new Uint8Array(res.data);
            const combined = new Uint8Array(incompleteChunk.length + newChunk.length);
            combined.set(incompleteChunk);
            combined.set(newChunk, incompleteChunk.length);
            
            const { text, remainder } = this.decodeUtf8Stream(combined);
            
            incompleteChunk = remainder; // Store new incomplete part for the next chunk
            
            const chunkText = text;
            if (!chunkText) return; // Nothing to process

          console.log('--- Raw Chunk Received ---\n' + chunkText + '\n--------------------------');
          buffer += chunkText;
          
          // 处理完整的事件（以\n\n分隔）
          while (buffer.includes('\n\n')) {
            const eventEndIndex = buffer.indexOf('\n\n');
            const eventMessage = buffer.substring(0, eventEndIndex);
            buffer = buffer.substring(eventEndIndex + 2); // 移除已处理的事件和分隔符
            
            if (!eventMessage.trim()) continue;
            
            // 解析事件类型和数据
            const lines = eventMessage.split('\n');
            let eventType = '';
            let dataStr = '';
            
            for (const line of lines) {
              if (line.startsWith('event:')) {
                eventType = line.substring('event:'.length).trim();
              } else if (line.startsWith('data:')) {
                dataStr = line.substring('data:'.length).trim();
        }
            }
            
            if (!eventType || !dataStr) continue;
            
            console.log(`处理事件: ${eventType}`);
              
              this.processEvent(eventType, dataStr, tempMessage.id, aiMessageIndex);
              
              // 更新aiMessageIndex如果它已经被设置
              if (aiMessageIndex === -1) {
                aiMessageIndex = this.messages.findIndex(m => m.id === tempMessage.id);
              }
            }
          } catch (error) {
            console.error('处理数据块时出错:', error);
            // 不要立即显示错误，继续尝试处理其他数据块
            // 如果所有数据块处理完毕后内容为空，再显示错误
          }
        });
        
        // 添加请求完成事件处理
        requestTask.onHeadersReceived((res) => {
          console.log('Headers received:', res);
          // 检查是否有错误状态码
          if (res.statusCode && res.statusCode !== 200) {
            clearTimeout(requestTimeout);
            this.handleStreamError(tempMessage.id, `请求失败 (${res.statusCode})，请稍后再试。`);
          }
        });
        
      } catch (error) {
        // 清除超时定时器
        clearTimeout(requestTimeout);
        
        console.error('创建请求时出错:', error);
        this.handleNetworkError(tempMessage.id, error);
      }
    },
    
    // 处理特定事件类型
    processEvent(eventType, dataStr, messageId, currentIndex) {
      try {
        let aiMessageIndex = currentIndex;
            
            if (eventType === 'Message') {
          try {
              const data = JSON.parse(dataStr);
              console.log('--- Parsed Message Data ---\n' + JSON.stringify(data, null, 2) + '\n---------------------------');
              
              if (aiMessageIndex === -1) {
                // 找到临时消息并替换
              aiMessageIndex = this.messages.findIndex(m => m.id === messageId);
                if (aiMessageIndex !== -1) {
                  // 清空"正在思考中..."，准备接收真实内容
                  this.$set(this.messages[aiMessageIndex], 'content', '');
                  this.$set(this.messages[aiMessageIndex], 'status', 'streaming');
                }
              }
              
            if (aiMessageIndex === -1) return aiMessageIndex;
              
              // 处理消息内容
              if (data.content) {
                try {
                  // 尝试解析内容为JSON
                  const parsedContent = JSON.parse(data.content);
                  
                  // 检查是否包含output字段（最终结果）
                  if (parsedContent.output && typeof parsedContent.output === 'string') {
                    try {
                      // 解析嵌套的output字段
                      const outputData = JSON.parse(parsedContent.output);
                      
                      if (outputData.content) {
                        // 使用打字机效果显示内容
                        this.simulateTyping(aiMessageIndex, outputData.content);
                      
                      // 在每次收到消息时触发滚动到底部
                      this.scrollToBottom();
                      }
                    } catch (e) {
                      console.error('解析output字段失败:', e);
                      // 如果解析失败，直接显示output字段
                      if (parsedContent.output) {
                        this.simulateTyping(aiMessageIndex, parsedContent.output);
                      
                      // 在每次收到消息时触发滚动到底部
                      this.scrollToBottom();
                      }
                    }
                  } else {
                    // 如果没有output字段，尝试查找其他可能的内容字段
                    const content = parsedContent.content || parsedContent.text || JSON.stringify(parsedContent);
                  this.$set(this.messages[aiMessageIndex], 'content', this.messages[aiMessageIndex].content + content);
                  
                  // 在每次收到消息时触发滚动到底部
                  this.scrollToBottom();
                  }
                } catch (e) {
                  // 解析失败，说明是普通文本，直接追加
                  console.log('接收到普通文本块');
                this.$set(this.messages[aiMessageIndex], 'content', this.messages[aiMessageIndex].content + data.content);
                
                // 在每次收到消息时触发滚动到底部
                this.scrollToBottom();
                }
            }
          } catch (parseError) {
            console.error('解析Message事件数据失败:', parseError);
              }
            } else if (eventType === 'Done') {
              console.log('流式传输完成');
              // 如果没有通过simulateTyping方法处理，确保状态更新
              if (aiMessageIndex !== -1 && this.messages[aiMessageIndex].status === 'streaming') {
                this.$set(this.messages[aiMessageIndex], 'status', 'sent');
                
                // 调用handleStreamResult处理最终结果并自动合成语音
            this.handleStreamResult(messageId, this.messages[aiMessageIndex].content);
              }
        this.isLoadingResponse = false;
        
              // 更新conversation_id（如果有）
              try {
                const doneData = JSON.parse(dataStr);
                if (doneData.conversation_id) {
                  this.cozeApi.conversationId = doneData.conversation_id;
        }
              } catch (e) {
                console.error("解析Done事件失败:", e);
              }
            } else if (eventType === 'Error') {
              console.error('收到错误事件');
              try {
                const errorData = JSON.parse(dataStr);
            this.handleStreamError(messageId, `发生错误: ${errorData.error_message || '未知错误'}`);
              } catch (e) {
            this.handleStreamError(messageId, '处理响应时出错');
              }
            }
        
        return aiMessageIndex;
      } catch (error) {
        console.error(`处理${eventType}事件时出错:`, error);
        return currentIndex;
      }
    },

    // 处理网络错误，提供更详细的错误信息
    handleNetworkError(messageId, error) {
      let errorMessage = '网络连接错误，请检查网络设置。';
      
      // 分析具体错误类型
      if (error && error.errMsg) {
        if (error.errMsg.includes('request:fail')) {
          if (error.errMsg.includes('timeout')) {
            errorMessage = '连接超时，服务器响应时间过长。';
          } else if (error.errMsg.includes('abort')) {
            errorMessage = '请求被中断，请稍后再试。';
          } else if (error.errMsg.includes('socket error')) {
            errorMessage = '网络连接断开，请检查网络状态。';
          } else if (error.errMsg.includes('SSL')) {
            errorMessage = '网络安全验证失败，请稍后再试。';
          } else if (error.errMsg.includes('dns')) {
            errorMessage = 'DNS解析失败，无法连接到服务器。';
      }
        }
      }
      
      // 在UI上显示错误信息
      this.handleStreamError(messageId, `${errorMessage}(ERR_CONNECTION_CLOSED)`);
      
      // 提供重试功能
      this.addRetryOption(messageId);
    },

    // 添加重试选项
    addRetryOption(messageId) {
      const index = this.messages.findIndex(m => m.id === messageId);
      if (index !== -1) {
        // 添加重试按钮或提示
        this.$set(this.messages[index], 'canRetry', true);
      }
    },

    handleStreamError(messageId, errorMessage) {
      const errorIndex = this.messages.findIndex(m => m.id === messageId);
      if (errorIndex !== -1) {
        // 更新为错误状态
        this.$set(this.messages[errorIndex], 'content', errorMessage);
        this.$set(this.messages[errorIndex], 'status', 'error');
        // 添加可重试标记
        this.$set(this.messages[errorIndex], 'canRetry', true);
      } else {
        // 如果找不到消息，创建一个错误消息
        const errorMsg = {
          id: 'error-' + Date.now().toString(),
          type: 'text',
          sender: 'bot',
          content: errorMessage,
          timestamp: Date.now(),
          status: 'error',
          canRetry: true
        };
        this.messages.push(errorMsg);
      }
      this.isLoadingResponse = false;
      this.scrollToBottom();
    },
    
    simulateTyping(index, fullText) {
      if (index === -1 || !fullText) {
        this.isLoadingResponse = false;
        return;
      }
    
      // 处理文本格式（将 ** 包围的文本转换为加粗大字的 HTML）
      const formattedText = this.formatMessageContent(fullText);
      
      let charIndex = 0;
      // 确保内容为空，准备接收打字机效果的文本
      this.$set(this.messages[index], 'content', ''); 
    
      const intervalId = setInterval(() => {
        if (charIndex < formattedText.length) {
          this.messages[index].content += formattedText[charIndex];
          charIndex++;
          // 使用新的滚动到底部方法
          this.scrollToBottom();
            } else {
          clearInterval(intervalId);
          this.messages[index].status = 'sent';
          this.isLoadingResponse = false;
          
          // 打字机效果完成后，调用handleStreamResult处理最终结果并自动合成语音
          const messageId = this.messages[index].id;
          const finalContent = this.messages[index].content;
          this.handleStreamResult(messageId, finalContent);
        }
      }, 30); // 打字速度，单位：毫秒
    },
    
    // 格式化消息内容，处理特殊标记
    formatMessageContent(text) {
      if (!text) return '';
      
      // 第一步：将数字编号的小标题前添加换行标签（如果不是已经在行首）
      let formattedText = text.replace(/([^\n])([\d]+\.\s*\*\*)/g, '$1<br/><br/>$2');
      
      // 第二步：确保小标题后的内容也正确换行
      formattedText = formattedText.replace(/(\*\*.*?\*\*:?)([^\n])/g, '$1<br/>$2');
      
      // 第三步：将 **文本** 转换为带有样式的 HTML 标签
      formattedText = formattedText.replace(/\*\*(.*?)\*\*/g, '<strong style="font-weight: bold; font-size: 1.2em; color: #333;">$1</strong>');
      
      // 第四步：增强段落间距，使结构更清晰
      formattedText = formattedText.replace(/\n/g, '<br/>');
      
      return formattedText;
    },
    
    // 模拟AI回复（用于开发测试或API不可用时）
    simulateAIResponse(userInput) {
      // 延迟模拟API响应时间
      setTimeout(() => {
        // 根据用户输入生成模拟回复
        let aiContent;
        
        if (userInput.includes('天气')) {
          aiContent = '今天天气晴朗，温度适宜，是个出门游玩的好日子！';
        } else if (userInput.includes('笑话') || userInput.includes('段子')) {
          aiContent = '程序员遇到了一个恐龙，恐龙问：「你为什么害怕我？」程序员说：「因为我还没提交的代码啊！」';
        } else if (userInput.includes('推荐') && userInput.includes('歌')) {
          aiContent = '推荐几首好听的歌曲：\n1. 《Blinding Lights》- The Weeknd\n2. 《星辰大海》- 黄霄雲\n3. 《起风了》- 买辣椒也用券';
        } else if (userInput.includes('旅游') || userInput.includes('景点')) {
          aiContent = '国内热门旅游景点推荐：\n1. 张家界：壮丽的自然风光和玻璃栈道\n2. 丽江古城：古色古香的街道和纳西文化\n3. 三亚：美丽的海滩和热带风情';
        } else {
          aiContent = '我是新如影，很高兴为您服务！您可以问我天气、笑话、音乐推荐或旅游建议等问题。';
        }
        
        // 创建新的AI消息
        const newAiMessage = {
          id: 'sim-' + Date.now().toString(),
          type: 'text',
          sender: 'bot',
          content: aiContent,
          timestamp: Date.now(),
          status: 'sent'
        };
        
        // 添加到消息列表
        this.messages.push(newAiMessage);
        
        // 滚动到最新消息
        this.scrollToBottom();
      }, 800);
    },
    
    // 修改重新生成消息的方法
    regenerateMessage(message) {
      uni.showToast({
        title: '正在重新生成回复',
        icon: 'none'
      });
      
      // 删除最后一条AI消息
      if (this.messages.length > 0 && this.messages[this.messages.length - 1].sender === 'bot') {
        this.messages.pop();
      }
      
      // 获取用户的最后一条消息
      let lastUserMessage = '';
      for (let i = this.messages.length - 1; i >= 0; i--) {
        if (this.messages[i].sender === 'user') {
          lastUserMessage = this.messages[i].content;
          break;
        }
      }
      
      // 如果找到了用户的最后一条消息，重新请求AI回复
      if (lastUserMessage) {
        this.fetchCozeResponse(lastUserMessage);
      } else {
        // 如果没有用户消息，使用默认提示语
        this.fetchCozeResponse('请给我一些有趣的内容');
      }
    },
    
    // 其他原有方法...
    
    toggleMute() {
      uni.showToast({
        title: '静音已切换',
        icon: 'none'
      });
    },
    makePhoneCall() {
      if (this.isVoicePlaying) {
        this.toggleVoicePlay();
        return;
      }

      if (this.lastBotMessageId) {
        // 播放最后一条AI消息的语音
        this.playTTSFromCache(this.lastBotMessageId);
      } else {
        // 找到最后一条AI消息
        const lastBotMessage = [...this.messages].reverse().find(m => m.sender === 'bot' && m.type === 'text');
        if (lastBotMessage) {
          this.lastBotMessageId = lastBotMessage.id;
          const plainText = lastBotMessage.content.replace(/<[^>]*>/g, '');
          if (plainText) {
            // 尝试播放或合成
              this.playTTSFromCache(lastBotMessage.id);
          } else {
            uni.showToast({ title: '没有可播放的文本内容', icon: 'none' });
          }
        } else {
          uni.showToast({ title: '未找到AI的最后一条回复', icon: 'none' });
        }
      }
    },
    startThinking() {
      uni.showToast({
        title: '深度思考中...',
        icon: 'none'
      });
    },
    playMusic() {
      uni.showToast({
        title: '播放音乐中...',
        icon: 'none'
      });
    },
    // 切换输入模式（文本/语音）
    toggleInputMode() {
      this.inputMode = this.inputMode === 'text' ? 'voice' : 'text';
    },
    // 切换功能按钮显示
    toggleFunctionButtons() {
      this.showFunctionButtons = !this.showFunctionButtons;
      this.moreButtonActive = this.showFunctionButtons; // 更新加号按钮状态
    },
    // 处理文本输入事件，调整高度和计算行数
    handleTextareaInput(e) {
      // 获取输入事件的值
      if (typeof e === 'object' && e.detail) {
        const text = e.detail.value || '';
        
        // 计算文本行数 - 优化行数计算
        let lines = 1;
        
        // 计算换行符数量
        const newLineCount = (text.match(/\n/g) || []).length;
        
        // 计算每行平均字符数
        const avgCharsPerLine = 20; // 假设平均每行20个字符
        const textWithoutNewlines = text.replace(/\n/g, '');
        const charsLineCount = Math.ceil(textWithoutNewlines.length / avgCharsPerLine);
        
        // 总行数是换行符数量+1与字符行数的最大值
        lines = Math.max(newLineCount + 1, charsLineCount);
        this.textLines = Math.max(1, Math.min(lines, 5)); // 行数范围在1-5之间
        
        // 根据行数调整文本框高度
        const lineHeight = 20; // 每行高度约为20px
        const baseHeight = 28; // 基础高度，从38px改为28px
        const calculatedHeight = baseHeight + ((this.textLines - 1) * lineHeight);
        this.textareaHeight = calculatedHeight;
        
        // 如果文本被清空，重置状态到初始状态
        if (!text.trim()) {
          this.resetInputState();
        }
        
        console.log('文本行数:', this.textLines, '文本高度:', this.textareaHeight);
      }
    },
    // 新增方法：重置输入状态到初始状态
    resetInputState() {
      this.textareaHeight = 28; // 重置高度到基础高度
      this.textLines = 1; // 重置行数
      this.showFunctionButtons = false; // 隐藏功能按钮
      this.moreButtonActive = false; // 重置加号按钮状态
      this.expandIconVisible = false; // 放大按钮隐藏
      this.inputMode = 'text'; // 确保恢复到文本输入模式
      
      // 确保立即应用样式更新
      this.$nextTick(() => {
        if (this.$refs.textarea) {
          this.$refs.textarea.style.height = '28px';
          
          // 重置文本区域样式
          const inputArea = document.querySelector('.input-area');
          if (inputArea) {
            // 确保高度一致
            inputArea.style.transition = 'all 0.3s ease';
          }
          
          // 确保按钮固定在底部
          const actionIcons = document.querySelector('.action-icons');
          if (actionIcons) {
            actionIcons.style.position = 'absolute';
            actionIcons.style.right = '12px';
            actionIcons.style.bottom = '15px'; // 保持与CSS一致
            // 移除top和transform设置
            actionIcons.style.top = '';
            actionIcons.style.transform = '';
          }
          
          // 确保相机图标底部对齐
          const cameraIcon = document.querySelector('.camera-icon');
          if (cameraIcon) {
            cameraIcon.style.alignSelf = 'flex-end';
            cameraIcon.style.marginBottom = '8px';
          }
        }
      });
    },
    // 处理输入框获取焦点
    handleTextareaFocus() {
      // 输入框获取焦点时隐藏功能按钮
      this.showFunctionButtons = false;
      this.moreButtonActive = false;
    },
    // 处理输入框失去焦点，确保状态正确
    handleTextareaBlur() {
      // 如果输入框为空，重置到初始状态
      if (!this.inputMessage.trim()) {
        this.resetInputState();
      }
    },
    // 展开大视图文本编辑器
    expandTextView() {
      this.isExpandedView = true;
      this.chatFooterHeight = this.expandedInputHeight;
      // 聚焦扩展文本框
      this.$nextTick(() => {
        // 延迟聚焦，确保视图已更新
        setTimeout(() => {
          const textarea = document.querySelector('.expanded-textarea');
          if (textarea) textarea.focus();
        }, 300);
      });
    },
    // 关闭大视图
    closeExpandedView() {
      this.isExpandedView = false;
    },
    // 选择图片
    chooseImage() {
      uni.chooseImage({
        count: 1,
        success: (res) => {
          const tempFilePath = res.tempFilePaths[0];
          
          // 模拟图片上传
          setTimeout(() => {
            // 发送图片消息
            this.sendImageMessage(tempFilePath);
          }, 500);
        }
      });
    },
    // 发送图片消息
    sendImageMessage(imageUrl, text = '') {
      // 创建新消息对象
      const newMessage = {
        id: Date.now().toString(),
        type: 'image',
        sender: 'user',
        content: {
          imageUrl,
          text
        },
        timestamp: Date.now(),
        status: 'sent'
      };
      
      // 添加到消息列表
      this.messages.push(newMessage);
      
      // 模拟AI回复
      this.simulateAIResponse('图片');
      
      // 滚动到最新消息
      this.scrollToLatestMessage();
    },
    // 开始录音
    startRecording() {
      this.recordingStart = Date.now();
      const platform = uni.getSystemInfoSync().platform;
      this.recorder.start({
        format: platform === 'devtools' ? 'pcm' : 'mp3',
        sampleRate: 16000,
        numberOfChannels: 1
      });
      
      uni.showToast({
        title: '正在录音...',
        icon: 'none',
        duration: 60000
      });
    },
    // 停止录音
    stopRecording() {
      uni.hideToast();
      this.recordDuration = Math.round((Date.now() - this.recordingStart) / 1000);
      this.recorder.stop();
    },
    // 取消录音
    cancelRecording() {
      uni.hideToast();
      this.recorder.stop();
      
      uni.showToast({
        title: '已取消录音',
        icon: 'none'
      });
    },
    // 发送语音消息
    sendVoiceMessage(audioUrl, duration) {
      // 创建新消息对象
      const newMessage = {
        id: Date.now().toString(),
        type: 'voice',
        sender: 'user',
        content: {
          audioUrl,
          duration
        },
        timestamp: Date.now(),
        status: 'sent'
      };
      
      // 添加到消息列表
      this.messages.push(newMessage);
      
      // 模拟AI回复
      this.simulateAIResponse('语音');
      
      // 滚动到最新消息
      this.scrollToLatestMessage();
    },
    // 播放语音消息
    playVoice(message) {
      // 检查是否正在播放该消息的语音
      if (this.isVoicePlaying && this.audioContext && 
          this.audioContext.src === message.content.audioUrl) {
        // 如果正在播放同一条消息的语音，则停止播放
        this.audioContext.stop();
        return;
      }
      
      if (!this.audioContext) {
        this.audioContext = uni.createInnerAudioContext();
      } else {
        // 如果有其他语音在播放，先停止
        if (this.audioContext.paused === false) {
          this.audioContext.stop();
        }
        if (this.ttsAudioContext && this.ttsAudioContext.paused === false) {
          this.ttsAudioContext.stop();
        }
      }
      
      this.audioContext.src = message.content.audioUrl;
      this.audioContext.play();
      
      // 监听播放结束
      this.audioContext.onEnded(() => {
        console.log('语音播放结束');
        this.isVoicePlaying = false;
      });
      
      // 监听播放错误
      this.audioContext.onError((res) => {
        console.error('语音播放失败', res);
        this.isVoicePlaying = false;
        uni.showToast({
          title: '语音播放失败',
          icon: 'none'
        });
      });
    },
    // 滚动到最新消息，优化滚动逻辑
    scrollToLatestMessage() {
      // 调用新的滚动到底部方法
      this.scrollToBottom();
    },
    // 加载更多历史消息
    loadMoreMessages() {
      // 实际应用中这里会加载更多历史消息
      console.log('加载更多历史消息');
    },
    // 处理话题点击
    handleTopicClick(topic) {
      // 将话题内容填入输入框
      this.inputMessage = topic;
      
      // 确保是文本输入模式
      this.inputMode = 'text';
      
      // 聚焦输入框
      this.$nextTick(() => {
        // 获取textarea的焦点
        const textareaElement = this.$refs.textarea;
        if (textareaElement) {
          textareaElement.focus();
        }
      });
    },
    // 切换语音播放状态
    toggleVoicePlay() {
      if (this.isVoicePlaying) {
        if (this.ttsAudioContext && this.ttsAudioContext.paused === false) {
          this.ttsAudioContext.stop();
        }
        if (this.audioContext && this.audioContext.paused === false) {
          this.audioContext.stop();
        }
      } else {
        // 如果当前没有播放，则触发播放最后一条消息
        this.makePhoneCall();
      }
    },
    // 模拟开始录音
    mockStartRecording() {
      this.isRecording = true;
      this.touchStartY = 0;
      this.isCancelling = false;
      
      // 启动波形动画
      this.startWaveAnimation();
      
      // 震动反馈
      uni.vibrateShort();
    },
    
    // 模拟停止录音
    mockStopRecording() {
      if (this.isCancelling) {
        this.mockCancelRecording();
        return;
      }
      
      this.isRecording = false;
      this.stopWaveAnimation();
      
      // 显示发送成功提示
      setTimeout(() => {
        uni.showToast({
          title: '语音已发送',
          icon: 'none',
          duration: 1500
        });
      }, 300);
    },
    
    // 模拟取消录音
    mockCancelRecording() {
      this.isRecording = false;
      this.stopWaveAnimation();
      
      // 显示取消提示
      setTimeout(() => {
        uni.showToast({
          title: '已取消录音',
          icon: 'none',
          duration: 1500
        });
      }, 300);
    },
    
    // 处理手指移动事件
    handleTouchMove(e) {
      if (!this.isRecording) return;
      
      if (!this.touchStartY) {
        this.touchStartY = e.touches[0].clientY;
      }
      
      const moveY = e.touches[0].clientY;
      const diffY = this.touchStartY - moveY;
      
      // 上滑超过50像素则切换到取消状态
      if (diffY > 50) {
        if (!this.isCancelling) {
          this.isCancelling = true;
          // 震动提示
          uni.vibrateShort();
        }
      } else {
        if (this.isCancelling) {
          // 从取消状态恢复到录音状态时也添加震动反馈
          uni.vibrateShort();
        }
        this.isCancelling = false;
      }
      
      // 调试信息
      console.log(`上滑距离: ${diffY}px, 取消状态: ${this.isCancelling}`);
    },
    
    // 启动波形动画
    startWaveAnimation() {
      // 清除可能存在的定时器
      this.stopWaveAnimation();
      
      // 创建新的定时器，模拟波形动画
      this.waveDotInterval = setInterval(() => {
        // 随机选择几个点高亮
        this.activeWaveDot = Math.floor(Math.random() * 70);
      }, 100);
    },
    
    // 停止波形动画
    stopWaveAnimation() {
      if (this.waveDotInterval) {
        clearInterval(this.waveDotInterval);
        this.waveDotInterval = null;
      }
    },
    // 复制消息内容
    copyMessage(message) {
      let content = '';
      if (message.type === 'text') {
        content = message.content;
      } else if (message.type === 'image' && message.content.text) {
        content = message.content.text;
      }
      
      if (content) {
        uni.setClipboardData({
          data: content,
          success: function() {
            uni.showToast({
              title: '已复制到剪贴板',
              icon: 'none'
            });
          }
        });
      }
    },
    // 播放TTS音频
    async playAudio(text) {
      if (this.isVoicePlaying) {
        if (this.ttsAudioContext && this.ttsAudioContext.paused === false) {
          this.ttsAudioContext.stop();
        }
        return;
      }
      
      if (!this.huoshanTTSApi.appid || !this.huoshanTTSApi.accessToken) {
      uni.showToast({
          title: '请先配置火山TTS的AppID和AccessToken',
          icon: 'none',
          duration: 3000
        });
        return;
      }
      
      // 生成临时ID并合成播放
      const tempId = 'temp-' + Date.now();
      this.synthesizeTTS(text, tempId);
    },
    
    // 生成UUID
    generateUUID() {
      return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = Math.random() * 16 | 0,
          v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
      });
    },
    
    isLastAssistantMessage(index) {
      if (this.messages[index].sender !== 'bot') {
        return false;
      }
      // 从当前消息往后找，如果再也找不到assistant的消息，说明是最后一条
      for (let i = index + 1; i < this.messages.length; i++) {
        if (this.messages[i].sender === 'bot') {
          return false;
        }
      }
      return true;
    },
    
    // 收藏消息
    favoriteMessage(message) {
      uni.showToast({
        title: '已收藏',
        icon: 'success'
      });
      // 实际应用中，这里会将消息添加到收藏列表
    },
    
    // 分享消息
    shareMessage(message) {
      uni.showToast({
        title: '分享功能开发中',
        icon: 'none'
      });
      // 实际应用中，这里会调用分享API
    },
    
    // 请求火山TTS API并播放
    fetchAndPlayTTS(textToSpeak) {
      // 找到最后一条AI消息
      const lastBotMessage = [...this.messages].reverse().find(m => m.sender === 'bot' && m.type === 'text');
      if (lastBotMessage) {
        // 使用消息ID播放或合成
          this.playTTSFromCache(lastBotMessage.id);
      } else {
        // 如果找不到消息ID，使用临时ID
        const tempId = 'temp-' + Date.now();
        this.synthesizeTTS(textToSpeak, tempId);
      }
    },
    // 处理流式输出的最终结果
    handleStreamResult(tempMessageId, finalContent) {
      // 找到临时消息的索引
      const tempIndex = this.messages.findIndex(m => m.id === tempMessageId);
      if (tempIndex !== -1) {
        // 更新消息内容
        this.messages[tempIndex].content = finalContent;
        this.messages[tempIndex].status = 'complete';
        this.messages[tempIndex].timestamp = Date.now();
        
        // 更新最后一条AI消息ID
        this.lastBotMessageId = this.messages[tempIndex].id;
        
        // 自动合成语音并缓存
        this.autoSynthesizeLastMessage();
      }
      
      this.isLoadingResponse = false;
      this.scrollToLatestMessage();
    },
    
    // 自动合成最后一条消息的语音
    autoSynthesizeLastMessage() {
      if (!this.lastBotMessageId) return;
      
      const lastBotMessage = this.messages.find(m => m.id === this.lastBotMessageId);
      if (!lastBotMessage || !lastBotMessage.content) return;
      
      const plainText = lastBotMessage.content.replace(/<[^>]*>/g, '');
      if (!plainText) return;
      
      // 静默合成语音，合成成功后会根据speakerEnabled状态自动播放
      this.synthesizeTTS(plainText, lastBotMessage.id, true);
    },
    
    // 将文本分割成段落
    splitTextIntoSegments(text, maxLength = 100) {
      console.log(`[TTS] 开始分段文本，总长度: ${text.length}，最大段长: ${maxLength}`);
      
      if (!text || text.length <= maxLength) {
        // 如果文本为空或长度小于等于最大长度，直接返回
        return [text];
      }
      
      // 初始化结果数组
      const segments = [];
      
      // 分段标点符号
      const breakPoints = ['。', '！', '？', '；', '，', '.', '!', '?', ';', ',', '\n'];
      
      // 当前位置和剩余文本
      let currentPos = 0;
      let remainingText = text;
      
      // 循环处理文本
      while (remainingText.length > 0) {
        // 如果剩余文本长度小于等于最大长度，直接添加并结束
        if (remainingText.length <= maxLength) {
          segments.push(remainingText);
          break;
        }
        
        // 在最大长度范围内查找最后一个分段标点
        let segmentEnd = maxLength;
        let foundBreakPoint = false;
        
        // 从后往前查找分段点
        for (let i = maxLength; i >= maxLength / 2; i--) {
          if (breakPoints.includes(remainingText[i])) {
            segmentEnd = i + 1; // 包含标点符号
            foundBreakPoint = true;
            break;
          }
        }
        
        // 如果没有找到合适的分段点，尝试在前半部分查找
        if (!foundBreakPoint) {
          for (let i = maxLength / 2; i > 0; i--) {
            if (breakPoints.includes(remainingText[i])) {
              segmentEnd = i + 1; // 包含标点符号
              foundBreakPoint = true;
              break;
            }
          }
        }
        
        // 如果仍然没有找到分段点，就在最大长度处截断
        if (!foundBreakPoint) {
          // 避免在单词中间截断（如果是英文文本）
          if (/[a-zA-Z]/.test(remainingText[segmentEnd - 1]) && /[a-zA-Z]/.test(remainingText[segmentEnd])) {
            // 向前查找空格
            for (let i = segmentEnd - 1; i > segmentEnd - 10 && i > 0; i--) {
              if (remainingText[i] === ' ') {
                segmentEnd = i + 1; // 在空格后截断
                break;
              }
            }
          }
        }
        
        // 添加当前段落
        segments.push(remainingText.substring(0, segmentEnd));
        
        // 更新剩余文本
        remainingText = remainingText.substring(segmentEnd);
        currentPos += segmentEnd;
      }
      
      console.log(`[TTS] 文本分段完成，共${segments.length}段`);
      
      // 更新当前处理的文本段落
      this.currentTextSegments = segments;
      
      return segments;
    },
    
    // 合成TTS并播放
    synthesizeTTS(text, messageId, silent = false) {
      console.log(`[TTS] 开始合成语音, 消息ID: ${messageId}, 文本长度: ${text ? text.length : 0}, 静默模式: ${silent}`);
      
      if (!text || text.trim().length === 0) {
        console.warn(`[TTS] 合成失败: 文本为空, 消息ID: ${messageId}`);
        return;
      }
      
      // 如果已经在合成中，先停止当前合成
      if (this.isSynthesizing) {
        console.log(`[TTS] 停止当前合成, 之前的消息ID: ${this.synthesizingMessageId}`);
        this.ttsStreamService.stop();
        // 确保隐藏之前可能显示的加载提示
        wx.hideLoading();
        this.isVoicePlaying = false; // 确保停止播放状态
        
        // 清除当前文本段落
        this.currentTextSegments = null;
      }
      
      // 设置合成状态
      this.isSynthesizing = true;
      this.synthesizingMessageId = messageId;
      
      // 如果文本太长，分段处理
      const maxLength = 20; // 每段最大字符数，减小单次处理的文本量但不要太小
      if (text.length > maxLength) {
        const segments = this.splitTextIntoSegments(text, maxLength);
        console.log(`[TTS] 文本过长(${text.length}字符)，已分为${segments.length}段处理`);
        
        // 更新当前处理的文本段落
        this.currentTextSegments = segments;
        
        // 处理第一段
        this.processTextSegment(segments, 0, messageId, silent);
      } else {
        // 短文本直接处理
        if (!silent) {
          wx.showLoading({ title: '语音合成中...' });
        }
        
        // 清除当前文本段落，因为不需要分段处理
        this.currentTextSegments = null;
        
        // 使用流式合成并播放
        console.log(`[TTS] 开始流式合成短文本, 消息ID: ${messageId}, 文本: ${text.substring(0, 30)}...`);
        this.ttsStreamService.streamSynthesizeAndPlay(text, messageId, silent, false)
          .then(success => {
            if (!silent) {
              wx.hideLoading();
            }
            
            if (!success) {
              console.error(`[TTS] 合成失败, 消息ID: ${messageId}`);
              if (!silent) {
                wx.showToast({
                  title: '语音合成失败',
                  icon: 'none'
                });
              }
              this.isVoicePlaying = false; // 确保失败时更新状态
            } else {
              console.log(`[TTS] 合成成功并开始播放, 消息ID: ${messageId}`);
              if (!silent) {
                this.isVoicePlaying = true; // 成功开始播放时设置状态
              } else {
                console.log(`[TTS] 静默模式，不设置播放状态，但仍然保持合成状态`);
                // 在静默模式下，不设置播放状态，但仍然保持合成状态一段时间，确保缓存完成
                setTimeout(() => {
                  if (this.synthesizingMessageId === messageId) {
                    console.log(`[TTS] 静默合成完成，清除合成状态, 消息ID: ${messageId}`);
                    this.isSynthesizing = false;
                    this.synthesizingMessageId = ''; // 使用空字符串而不是null
                  }
                }, 1000); // 延迟1秒后清除状态
                return; // 提前返回，避免立即清除状态
              }
            }
            
            // 无论成功失败，都重置合成状态
            this.isSynthesizing = false;
            this.synthesizingMessageId = ''; // 使用空字符串而不是null
          })
          .catch(error => {
            if (!silent) {
              wx.hideLoading();
            }
            
            this.isSynthesizing = false;
            this.synthesizingMessageId = ''; // 使用空字符串而不是null
            this.isVoicePlaying = false; // 确保错误时更新状态
            
            console.error(`[TTS] 流式合成出错, 消息ID: ${messageId}`, error);
            if (!silent) {
              wx.showToast({
                title: `合成失败: ${error.message || '未知错误'}`,
                icon: 'none',
                duration: 3000
              });
            }
          });
      }
    },
    // 切换扩音器状态
    toggleSpeaker() {
      this.speakerEnabled = !this.speakerEnabled;
      console.log('自动语音播放状态:', this.speakerEnabled ? '开启' : '关闭');
      
      // 显示当前状态的提示
      uni.showToast({
        title: this.speakerEnabled ? '已开启自动语音播放' : '已关闭自动语音播放',
        icon: 'none',
        duration: 2000
      });
      
      if (!this.speakerEnabled) {
        // 停止当前正在播放的语音
        this.ttsStreamService.stop();
        this.isVoicePlaying = false;
        this.synthesizingMessageId = null;
      } else if (this.lastBotMessageId) {
        // 如果开启了自动播放，并且有最后一条AI消息，则尝试播放
        setTimeout(() => {
          this.playTTSFromCache(this.lastBotMessageId);
        }, 500);
      }
    },
    // 计算输入区域高度
    calculateInputAreaHeight() {
      // 获取系统信息，计算安全区域
      uni.getSystemInfo({
        success: (res) => {
          // 获取安全区域的底部边距
          if (res.safeArea) {
            const safeAreaBottom = res.screenHeight - res.safeArea.bottom;
            // 更新输入区高度，考虑安全区域
            this.normalInputHeight = 170 + safeAreaBottom;
            this.expandedInputHeight = 320 + safeAreaBottom;
            this.chatFooterHeight = this.normalInputHeight;
          }
        }
      });
    },
    
    // 发送快捷消息
    sendQuickMessage(text) {
      // 创建新消息对象
      const newMessage = {
        id: Date.now().toString(),
        type: 'text',
        sender: 'user',
        content: text,
        timestamp: Date.now(),
        status: 'sent'
      };
      
      // 添加到消息列表
      this.messages.push(newMessage);
      
      // 滚动到最新消息
      this.scrollToLatestMessage();
      
      // 创建AI回复的临时消息（显示加载动画）
      const tempMessage = {
        id: 'temp-' + Date.now().toString(),
        type: 'text',
        sender: 'bot',
        content: '',
        timestamp: Date.now(),
        status: 'loading'
      };
      
      // 添加临时消息到列表
      this.messages.push(tempMessage);
      
      // 再次滚动确保显示加载动画
      this.scrollToLatestMessage();
      
      // 调用 Coze API 获取回复
      this.fetchCozeResponse(text, tempMessage.id);
    },
    
    goToLogin() {
      console.log('doubao_chat.vue中的goToLogin方法被调用');
      try {
        // 使用正确的路径格式
        uni.navigateTo({
          url: '../user/login/index',
          success: function() {
            console.log('跳转到登录页面成功');
          },
          fail: function(err) {
            console.error('跳转到登录页面失败:', err);
            // 尝试使用reLaunch作为备选方案
            uni.reLaunch({
              url: '../user/login/index'
            });
          }
        });
      } catch (e) {
        console.error('跳转出错:', e);
        // 最后尝试使用reLaunch
        uni.reLaunch({
          url: '../user/login/index'
        });
      }
    },
    // 处理来自扣子API的流式响应
    handleCozeStreamResponse(content, isEnd) {
      if (!this.currentResponseMessage) {
        // 创建新的AI回复消息
        const newMessage = {
          id: 'ai_' + Date.now().toString(),
          type: 'text',
          sender: 'bot',
          content: content,
          timestamp: Date.now(),
          status: isEnd ? 'sent' : 'loading'
        };
        
        this.currentResponseMessage = newMessage;
        this.messages.push(newMessage);
        
        // 保存最新AI消息ID用于TTS
        this.lastBotMessageId = newMessage.id;
        
        // 滚动到底部
        this.$nextTick(() => {
          this.scrollToBottom();
        });
      } else {
        // 更新现有回复
        this.currentResponseMessage.content = content;
        this.currentResponseMessage.status = isEnd ? 'sent' : 'loading';
        
        // 强制更新视图
        this.$forceUpdate();
        
        // 滚动到底部
        this.$nextTick(() => {
          this.scrollToBottom();
        });
      }
    },
    // 处理重试消息请求
    retryMessage(message) {
      // 显示正在重试的提示
      uni.showToast({
        title: '正在重试...',
        icon: 'none',
        duration: 1500
      });
      
      // 找到用户的最后一条消息
      let lastUserMessage = '';
      for (let i = this.messages.length - 1; i >= 0; i--) {
        if (this.messages[i].sender === 'user') {
          lastUserMessage = this.messages[i].content;
          break;
        }
      }
      
      // 如果找到了用户消息，使用它来重试
      if (lastUserMessage) {
        // 删除错误消息
        const errorIndex = this.messages.findIndex(m => m.id === message.id);
        if (errorIndex !== -1) {
          this.messages.splice(errorIndex, 1);
        }
        
        // 重新发送请求
        this.fetchCozeResponse(lastUserMessage);
      } else {
        // 如果没有找到用户消息，显示错误
        uni.showToast({
          title: '无法重试，找不到用户消息',
          icon: 'none',
          duration: 2000
        });
      }
    },
    // 从缓存播放TTS
    playTTSFromCache(messageId) {
      console.log(`[TTS] 尝试从缓存播放消息ID: ${messageId}`);
      
      if (this.isVoicePlaying && this.synthesizingMessageId === messageId) {
        // 如果当前正在播放这条消息的语音，则停止播放
        console.log(`[TTS] 停止当前播放的消息: ${messageId}`);
        this.ttsStreamService.stop();
        this.isVoicePlaying = false;
        this.synthesizingMessageId = ''; // 使用空字符串而不是null
        // 确保隐藏加载提示
        wx.hideLoading();
        return;
      }
      
      // 查找消息内容
      const message = this.messages.find(m => m.id === messageId);
      if (!message) {
        console.error(`[TTS] 找不到消息ID: ${messageId}`);
        wx.showToast({
          title: '找不到消息',
          icon: 'none'
        });
        return;
      }
      
      console.log(`[TTS] 找到消息: ${messageId}, 内容: ${message.content.substring(0, 30)}...`);
      
      // 设置合成状态，防止被其他播放中断
      this.isSynthesizing = true;
      this.synthesizingMessageId = messageId; // 用于标识当前播放的音频
      
      wx.showLoading({ title: '准备播放...' });
      
      this.ttsStreamService.playFromCache(messageId)
        .then(success => {
          wx.hideLoading();
          if (!success) {
            console.log(`[TTS] 缓存中不存在消息ID: ${messageId}，需要重新合成`);
            
            if (message && message.content) {
              const plainText = typeof message.content === 'string' 
                ? message.content.replace(/<[^>]*>/g, '') 
                : '';
              
              if (plainText && plainText.trim()) {
                console.log(`[TTS] 开始合成文本: ${plainText.substring(0, 30)}...`);
                // 直接合成并播放，不使用静默模式
                this.synthesizeTTS(plainText, messageId, false);
              } else {
                console.warn(`[TTS] 消息内容为空或无效: ${messageId}`);
                wx.hideLoading();
                wx.showToast({
                  title: '无法播放此类型消息',
                  icon: 'none'
                });
                this.synthesizingMessageId = ''; // 使用空字符串而不是null
                this.isVoicePlaying = false;
                this.isSynthesizing = false; // 清除合成状态
              }
            } else {
              console.error(`[TTS] 消息内容为空: ${messageId}`);
              wx.hideLoading();
              this.synthesizingMessageId = ''; // 使用空字符串而不是null
              this.isVoicePlaying = false;
              this.isSynthesizing = false; // 清除合成状态
            }
          } else {
            // 缓存播放成功，设置播放状态
            console.log(`[TTS] 成功从缓存播放: ${messageId}`);
            this.isVoicePlaying = true;
            
            // 监听播放结束，清除状态
            setTimeout(() => {
              if (!this.isVoicePlaying) {
                console.log(`[TTS] 缓存播放结束，清除合成状态: ${messageId}`);
                this.isSynthesizing = false;
                this.synthesizingMessageId = ''; // 确保设置为空字符串
              }
            }, 500); // 延迟检查播放状态
          }
        })
        .catch(error => {
          wx.hideLoading();
          console.error(`[TTS] 从缓存播放失败: ${messageId}`, error);
          this.synthesizingMessageId = ''; // 使用空字符串而不是null
          this.isVoicePlaying = false;
          this.isSynthesizing = false; // 清除合成状态
          
          // 尝试重新合成
          if (message && message.content) {
            const plainText = typeof message.content === 'string' 
              ? message.content.replace(/<[^>]*>/g, '') 
              : '';
            
            if (plainText && plainText.trim()) {
              console.log(`[TTS] 播放失败后尝试重新合成: ${plainText.substring(0, 30)}...`);
              setTimeout(() => {
                this.synthesizeTTS(plainText, messageId, false);
              }, 500);
              return;
            }
          }
          
          wx.showToast({
            title: '无法播放音频',
            icon: 'none'
          });
        });
    },
    // 处理文本段落
    processTextSegment(segments, index, messageId, silent = false) {
      if (index >= segments.length) {
        console.log(`[TTS] 所有段落处理完成，消息ID: ${messageId}`);
        this.isSynthesizing = false;
        // 不要直接设置为null，而是设置为空字符串
        this.synthesizingMessageId = ''; // 使用空字符串而不是null
        return;
      }
      
      const segment = segments[index];
      console.log(`[TTS] 处理第${index + 1}/${segments.length}段，长度: ${segment.length}，消息ID: ${messageId}`);
      
      // 只在第一段显示加载提示
      if (index === 0 && !silent) {
        wx.showLoading({ title: '语音合成中...' });
      }
      
      // 合成当前段落
      this.ttsStreamService.streamSynthesizeAndPlay(segment, `${messageId}-seg${index}`, silent, true)
        .then(success => {
          // 只在第一段隐藏加载提示
          if (index === 0 && !silent) {
            wx.hideLoading();
          }
          
          if (!success) {
            console.error(`[TTS] 段落${index + 1}合成失败，消息ID: ${messageId}`);
            if (!silent) {
              wx.showToast({
                title: '语音合成失败',
                icon: 'none'
              });
            }
            this.isSynthesizing = false;
            this.isVoicePlaying = false;
            // 设置为空字符串而不是null
            this.synthesizingMessageId = '';
          } else {
            console.log(`[TTS] 段落${index + 1}合成成功，消息ID: ${messageId}`);
            
            // 设置播放状态
            if (!silent) {
              this.isVoicePlaying = true;
            }
            
            // 处理下一段的逻辑已经移到onSegmentEnd回调中处理
            // 这里不需要再设置定时器，但仍然保留安排下一段的日志
            console.log(`[TTS] 安排处理下一段 ${index + 2}/${segments.length}`);
            
            // 注意：不再需要设置定时器，因为我们现在依赖onSegmentEnd回调
            // 但为了兼容性和安全起见，仍然设置一个较长的超时定时器作为备份
            setTimeout(() => {
              // 检查是否仍在合成状态，避免用户手动停止后继续播放
              if (this.isSynthesizing && this.synthesizingMessageId === messageId) {
                console.log(`[TTS] 备份定时器触发，处理下一段 ${index + 2}/${segments.length}`);
                this.processTextSegment(segments, index + 1, messageId, silent);
              } else {
                console.log(`[TTS] 合成已被中断，不再处理下一段`);
                // 确保在中断时也设置为空字符串
                this.synthesizingMessageId = '';
              }
            }, 5000); // 使用更长的延迟时间作为备份
          }
        })
        .catch(error => {
          // 只在第一段隐藏加载提示
          if (index === 0 && !silent) {
            wx.hideLoading();
          }
          
          console.error(`[TTS] 段落${index + 1}合成出错，消息ID: ${messageId}`, error);
          if (!silent) {
            wx.showToast({
              title: `合成失败: ${error.message || '未知错误'}`,
              icon: 'none'
            });
          }
          
          this.isSynthesizing = false;
          this.isVoicePlaying = false;
          // 设置为空字符串而不是null
          this.synthesizingMessageId = '';
        });
    },
    // 停止TTS播放
    stopTTS() {
      console.log(`[TTS] 停止TTS播放，当前消息ID: ${this.synthesizingMessageId}`);
      this.ttsStreamService.stop();
      this.isVoicePlaying = false;
      this.isSynthesizing = false;
      this.synthesizingMessageId = ''; // 使用空字符串而不是null
      // 确保隐藏加载提示
      wx.hideLoading();
    },
    // 初始化TTS服务
    initTTSService() {
      // 创建TTS服务实例
      this.ttsStreamService = new TTSStreamService({
        appId: 'your_app_id', // 实际应用中替换为真实的appId
        accessKey: 'your_access_key', // 实际应用中替换为真实的accessKey
        onStart: () => {
          console.log('流式TTS开始播放');
          this.isVoicePlaying = true; // 设置播放状态
        },
        onData: (data) => {
          console.log('收到流式TTS数据块');
        },
        onEnd: () => {
          console.log('流式TTS播放结束');
          this.isVoicePlaying = false; // 清除播放状态
          
          // 如果不是分段播放，清除合成状态
          if (!this.isSynthesizing) {
            this.synthesizingMessageId = ''; // 使用空字符串而不是null
          }
        },
        onError: (error) => {
          console.error('流式TTS错误:', error);
          this.isVoicePlaying = false; // 清除播放状态
          this.isSynthesizing = false; // 清除合成状态
          this.synthesizingMessageId = ''; // 使用空字符串而不是null
          
          // 显示错误提示
          wx.showToast({
            title: `语音播放错误: ${error.message || '未知错误'}`,
            icon: 'none'
          });
        },
        onSegmentEnd: (segmentId) => {
          // 分段播放结束的回调
          console.log(`流式TTS分段播放结束: ${segmentId}`);
          
          // 从segmentId中提取基础消息ID和段索引
          if (segmentId && segmentId.includes('-seg')) {
            const parts = segmentId.split('-seg');
            const baseId = parts[0];
            const segIndex = parseInt(parts[1]);
            
            // 通知processTextSegment方法该段已播放完成
            this.handleSegmentEnd(baseId, segIndex);
          }
        }
      });
    },
    
    // 处理分段播放结束
    handleSegmentEnd(baseMessageId, segIndex) {
      console.log(`[TTS] 段落${segIndex + 1}播放完成，消息ID: ${baseMessageId}`);
      
      // 检查是否还在合成状态
      if (this.isSynthesizing && this.synthesizingMessageId === baseMessageId) {
        // 获取当前正在处理的文本段落
        const currentSegments = this.currentTextSegments;
        if (currentSegments && currentSegments.length > 0) {
          // 计算下一段索引
          const nextSegIndex = segIndex + 1;
          
          // 如果还有下一段，继续处理
          if (nextSegIndex < currentSegments.length) {
            console.log(`[TTS] 段落${segIndex + 1}播放完成，开始处理下一段 ${nextSegIndex + 1}/${currentSegments.length}`);
            
            // 短暂延迟后处理下一段，避免连续播放时的卡顿
            setTimeout(() => {
              if (this.isSynthesizing && this.synthesizingMessageId === baseMessageId) {
                this.processTextSegment(currentSegments, nextSegIndex, baseMessageId, false);
              } else {
                console.log(`[TTS] 合成已被中断，不再处理下一段`);
              }
            }, 100);
          } else {
            // 所有段落处理完成
            console.log(`[TTS] 所有段落播放完成，消息ID: ${baseMessageId}`);
            this.isSynthesizing = false;
            this.synthesizingMessageId = ''; // 使用空字符串而不是null
            this.currentTextSegments = null; // 清除当前文本段落
          }
        } else {
          console.warn(`[TTS] 找不到当前文本段落，无法继续处理`);
          this.isSynthesizing = false;
          this.synthesizingMessageId = ''; // 使用空字符串而不是null
        }
      }
    },
  },
  watch: {
    messages(newMessages, oldMessages) {
      // 检查是否有新AI消息
      if (newMessages.length > oldMessages.length) {
        const newMsg = newMessages[newMessages.length - 1];
        // 无论是否自动播放，都确保滚动到最新消息
        this.$nextTick(() => {
          this.scrollToLatestMessage();
        });
        
        if (newMsg.sender === 'bot' && this.speakerEnabled) {
          // 自动播放AI语音
          if (newMsg.type === 'voice') {
            this.playVoice(newMsg);
          } else if (newMsg.type === 'text') {
            // 文字消息自动TTS
            this.lastBotMessageId = newMsg.id;
            const plainText = newMsg.content.replace(/<[^>]*>/g, '');
            if (this.ttsAudioCache[newMsg.id]) {
              this.playTTSFromCache(newMsg.id);
            } else {
              this.synthesizeTTS(plainText, newMsg.id);
            }
          }
        }
      }
    }
  }
}
</script>

<style lang="scss">
.doubao-chat-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background-color: #f5f5f5;
  position: relative;
  padding-top: 10px; /* 移除顶部padding */
  padding-left: 15px; /* 移除底部padding */
}

/* 
  消息列表的样式已迁移至 ChatMessages.vue 组件，
  此处仅保留 chat-content 的基本布局样式，用于占位。
*/
.chat-content {
  /* 这个类名现在仅作为 <chat-messages> 组件的容器占位，
     主要的滚动和布局样式由子组件内部的 .chat-messages-component 控制。
     保留 flex: 1 是为了确保它能正确填充父容器的可用空间。 */
  flex: 1;
  display: flex; /* 让子组件可以撑满 */
  flex-direction: column;
  overflow: hidden; /* 防止内容溢出 */
}

.chat-footer {
  background-color: #ffffff;
  padding: 8px 0;
  border-top: none;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 10;
  padding-bottom: calc(8px + env(safe-area-inset-bottom));
  box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05); /* 添加阴影，增强层次感 */
  
  &.expanded-view {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    top: 0;
    padding: 0;
    z-index: 999;
  }
  
  &.recording-active {
    .slider-buttons-area {
      display: none !important; // 确保在录音状态下完全隐藏滑动按钮区域
    }
  }
  
  .slider-buttons-area {
    padding: 5px 0;
    background-color: #ffffff;
    border-bottom: none;
    margin-bottom: 5px;
  }
  
  .slider-scroll {
    width: 100%;
    white-space: nowrap;
    padding: 0 16px;
  }
  
  .slider-buttons {
    display: inline-flex;
    padding: 5px 0;
  }
  
  .slider-button {
    display: flex;
    flex-direction: row;
    align-items: center;
    padding: 8px 16px;
    margin-right: 12px;
    background-color: #f5f5f5;
    border-radius: 24px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
    
    image {
      width: 18px;
      height: 18px;
      margin-right: 6px;
    }
    
    text {
      font-size: 14px;
      color: #333;
      white-space: nowrap;
    }
    
    &:active {
      background-color: #eaeaea;
    }
  }
  
  .input-area {
    display: flex;
    align-items: flex-start;
    background-color: #f5f5f5;
    border-radius: 20px;
    padding: 8px 12px;
    margin: 0 16px;
    box-shadow: 0 3px 15px rgba(0, 0, 0, 0.1), 0 1px 5px rgba(0, 0, 0, 0.08);
    position: relative;
    min-height: 28px;
    transition: all 0.3s ease; // 添加过渡效果
    
    .camera-icon {
      margin-right: 10px;
      display: flex;
      align-items: center;
      align-self: flex-end; // 改回到底部对齐
      margin-bottom: 8px; // 恢复底部边距
      
      .input-icon {
        width: 24px;
        height: 24px;
        opacity: 0.8;
      }
    }
    
    .input-wrapper {
      flex: 1;
      position: relative;
      transition: all 0.3s ease;
      padding-right: 40px; // 默认右边距 - 只有发送按钮时的间距
      
      // 当有语音按钮时的右边距
      &.with-voice-button {
        padding-right: 70px; // 增加右边距，为语音按钮和发送按钮腾出空间
      }
      
      &.expanded-input {
        margin-left: 0; // 当输入时移除左边距，利用相机图标的空间
      }
      
      .message-input {
        width: 100%;
        min-height: 28px;
        max-height: 100px;
        font-size: 15px;
        background-color: transparent;
        color: #333;
        padding: 8px 0;
        line-height: 1.4;
        box-sizing: border-box;
        transition: all 0.3s ease; // 添加过渡效果
      }
      // 放大按钮
      .expand-icon {
        position: absolute;
        width: 24px;
        height: 24px;
        display: flex;
        align-items: center;
        justify-content: center;
        z-index: 1;
        transition: opacity 0.3s ease; // 添加过渡效果
        
        &.top-right {
          right: 8px;
          top: 2px; // 定位在右上角
        }
        
        image {
          width: 20px;
          height: 20px;
          opacity: 0.7;
        }
      }
    }
    // 语音输入框
    .voice-input-wrapper {
      flex: 1;
      display: flex;
      align-items: center;
      padding: 0 16px;
      
      .voice-button {
        width: 100%;
        height: 36px;
        line-height: 36px;
        text-align: center;
        color: #666;
        font-size: 15px;
        background-color: #f5f5f5; // 保持与整体背景相同颜色
        border-radius: 18px;
        // 移除按钮自身的阴影
        box-shadow: none;
        
        &:active {
          background-color: #e0e0e0;
          color: #0078ff;
        }
      }
    }
    
    .action-icons {
      position: absolute; 
      right: 12px;
      bottom: 15px;
      display: flex;
      align-items: center;
      z-index: 5; // 确保按钮始终显示在上层
      
      .action-icon {
        padding: 0 4px;
        display: flex;
        align-items: center;
        
        // 语音图标
        &.voice-icon {
          margin-right: 8px;
        }
        
        // 输入框图标
        .input-icon {
          width: 24px;
          height: 24px;
          opacity: 0.9;
          transition: all 0.3s ease;
        }
      }
    }
  }
  
  // 修复图片路径和优化扩展输入区域
  .input-expanded-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 999;
    display: flex;
    flex-direction: column;
    
    // 半透明背景覆盖层
    .expanded-header-overlay {
      flex: 0.4; // 顶部占40%高度
      background-color: rgba(0, 0, 0, 0.2); // 
    }
    
    // 扩展输入区域
    .expanded-input-area {
      flex: 0.6; // 输入区域占60%高度
    background-color: #fff;
      border-radius: 20px 20px 0 0; // 增大圆角
      overflow: hidden;
      position: relative;
      display: flex;
      flex-direction: column;
      box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.1); // 添加阴影
      
      // 扩展区域头部
    .expanded-header {
      display: flex;
        justify-content: center;
        align-items: center;
        padding: 16px;
        position: relative;
      border-bottom: 1px solid #f0f0f0;
      
        .title {
        font-size: 16px;
          font-weight: 500;
        }
        
        .shrink-icon-expanded {
          position: absolute;
          right: 16px;
          top: 50%;
          transform: translateY(-50%);
          width: 24px;  // 调整为合适大小
          height: 24px; // 调整为合适大小
          display: flex;
          align-items: center;
          justify-content: center;
          
          image {
            width: 18px;  // 图标实际大小
            height: 18px; // 图标实际大小
          }
        }
      }
      
      // 扩展区域文本框
    .expanded-textarea {
      flex: 1;
      width: 100%;
      font-size: 16px;
        line-height: 24px;
        padding: 16px 16px 60px 16px; // 底部增加更多padding，避免被发送按钮遮挡
      box-sizing: border-box;
      border: none;
    }
      
      // 修改发送按钮样式
      .send-expanded-button {
        position: absolute;
        right: 16px;
        bottom: 16px;
        width: 40px;
        height: 40px;
        border-radius: 20px;
        background-color: #f5f2f2; // 调整为发送按钮的 
        display: flex;
        align-items: center;
        justify-content: center;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
        z-index: 10;
        
        image {
          width: 18px;
          height: 18px;
        }
      }
    }
  }
}

// 录音状态遮罩层样式
.recording-overlay {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  background-color: transparent; // 完全透明背景，使聊天内容可见
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end; // 底部对齐
  z-index: 10001; // 确保在所有元素之上
  
  // 提示文本容器，添加背景和渐变效果
  .recording-tip-container {
    position: absolute;
    bottom: calc(44px + 16px + env(safe-area-inset-bottom)); // 定位到波形区域上方
    left: 0;
    right: 0;
    height: 120px; // 增加高度以适应渐变效果
    background: linear-gradient(to bottom, rgba(255,255,255,0) 0%, rgba(255,255,255,0.8) 30%, rgba(255,255,255,1) 60%, rgba(255,255,255,1) 100%);
    z-index: 10002;
    display: flex;
    align-items: flex-end; // 改为底部对齐
    justify-content: center;
    padding-bottom: 15px; // 添加底部间距
  }
  
  // 松手发送，上移取消 提示文本
  .recording-tip {
    text-align: center;
    
    text {
      display: inline-block;
      color: #333333;
      font-size: 14px;
      padding: 8px 16px;
      background-color: #ffffff; // 改为白色背景
      border-radius: 16px;
      white-space: nowrap;
      box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); // 添加轻微阴影
    }
    
    // 取消状态下的样式
    &.cancel-tip text {
      color: #ff453a; // 红色文字
    }
  }
  
  // 蓝色波形区域 - 位置和大小与输入框一致
  .recording-wave-area {
    width: calc(100% - 32px); // 与输入框宽度一致
    margin: 0 16px; // 与输入框外边距一致
    height: 44px; // 精确匹配输入框高度
    background-color: #0066ff; // 蓝色背景
    border-radius: 22px; // 与输入框圆角一致
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    position: relative;
    box-shadow: 0 3px 15px rgba(0, 0, 0, 0.1), 0 1px 5px rgba(0, 0, 0, 0.08); // 与输入框阴影一致
    margin-bottom: calc(8px + env(safe-area-inset-bottom)); // 底部边距
    padding: 0; // 移除内边距
    box-sizing: border-box; // 确保边框计算正确
    transition: all 0.3s ease; // 添加过渡效果
    
    // 取消状态下变为红色
    &.cancel-state {
      background-color: #ff453a; // 红色背景
    }
    
    // 波形点容器
    .recording-wave-dots {
      width: 90%;
      display: flex;
      justify-content: space-between;
      align-items: center;
      height: 100%;
      
      // 波形点样式
      .wave-dot {
        width: 1.5px;
        height: 5px;
        background-color: #fff;
        border-radius: 0px;
        transition: height 0.15s ease;
        
        // 激活状态的波形点
        &.wave-dot-active {
          height: 8px;
        }
      }
    }
  }
}

// 确保录音状态下隐藏其他按钮
.input-area.recording {
  opacity: 0; // 使用透明度而非display:none
  pointer-events: none; // 禁用点击
}

/* 小标题样式 */
.subtitle {
  font-weight: bold;
  font-size: 1.2em;
  color: #333;
}

/* 功能按钮样式 */
.function-buttons {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  background-color: #ffffff;
  border-radius: 8px;
  padding: 16px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  
  .function-button {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 22%;
    margin-bottom: 12px;
    
    .function-icon {
      width: 40px;
      height: 40px;
      margin-bottom: 8px;
      padding: 10px;
      background-color: #f5f5f5;
      border-radius: 50%;
    }
    
    .function-text {
      font-size: 12px;
      color: #333;
    }
  }
}

// 添加思考中的动画样式
.thinking-dots {
  display: inline-block;
  &::after {
    content: '';
    animation: thinking 1.5s infinite;
  }
}

@keyframes thinking {
  0% { content: '.'; }
  33% { content: '..'; }
  66% { content: '...'; }
  100% { content: '.'; }
}

// 加载状态的消息样式
.message-bubble.loading {
  display: flex;
  align-items: center;
  padding: 12px 16px;
  
  .loading-spinner {
    width: 16px;
    height: 16px;
    margin-right: 10px;
    border: 2px solid rgba(0, 120, 255, 0.2);
    border-top: 2px solid #0078ff;
    border-radius: 50%;
    animation: spin 1s linear infinite;
  }
  
  .loading-text {
    font-size: 15px;
    color: #666;
  }
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
</style>